package com.xframe.common.core.service.command;

import com.xframe.common.config.CommandRunTimeArgs;
import com.xframe.domain.repository.SysBaseRepository;
import com.xframe.domain.role.IUserCredentials;
import com.xframe.domain.sys.SysModel;
import com.xframe.domain.CommandModel;
import com.xframe.common.core.dto.ErrorCode;
import com.xframe.common.core.exception.BusinessException;
import com.xframe.domain.ModelRepositoryFactory;
import com.xframe.event.bus.core.model.DataMessage;
import com.xframe.event.bus.core.msg.MessageSender;
import com.xframe.xdal.core.exception.DalFrameException;
import com.xframe.xdal.core.model.IModel;
import com.xframe.xdal.core.model.mapping.ITableInfo;
import com.xframe.xdal.core.util.StringUtil;
import org.apache.commons.lang3.ObjectUtils;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @Description: 根据一组ID删除一批对象
 * @ClassName: DeleteProc
 * @Author: xufeng
 * @CreateTime: 2023/4/6
 **/
public class DeleteProc extends BaseCommand {


    @Override
    public Object ProcCommand(CommandModel requestArgs, IUserCredentials userCredentials) throws BusinessException {

        try {
            Map<String, Object> dto = requestArgs.getCommandBodyByMap();
            if (StringUtil.isEmpty(dto)) {
                throw new DalFrameException(com.xframe.xdal.core.constant.ErrorCode.ARGS_ERROR, "commandBody不能为null");
            }
            String modelCode = requestArgs.getModelCode();
            if (ObjectUtils.isEmpty(modelCode)) {
                throw new DalFrameException(com.xframe.xdal.core.constant.ErrorCode.ARGS_ERROR, "modelId不能为null");
            }
            SysModel sysModel = SysModel.getInstance(modelCode);
            if (ObjectUtils.isEmpty(sysModel)) {
                throw new DalFrameException(com.xframe.xdal.core.constant.ErrorCode.ARGS_ERROR, "modelCode为" + modelCode + "的模型不存在或已被删除");
            }
            SysBaseRepository repository = ModelRepositoryFactory.builder(sysModel);

            if(dto.containsKey("ids")) {
                List<String> ids = (List<String>) dto.get("ids");
                //String pkName = sysModel.findPkField();
                //repository.deleteById(ids,sysModel);
                for (String id : ids) {
                    this.execRepository(repository, "deleteById", id, sysModel);
                }
                MessageSender messageSender = MessageSender.getMessageSender();
                DataMessage dataMessage = DataMessage.valueOf(sysModel.getModelCode(), DataMessage.DELETE_IDS, StringUtil.EMPTY,
                        null, ids, requestArgs.getSysCode(), userCredentials.getName());
                messageSender.sendMsg("messageSynchronization", dataMessage);
                return ids.size();
            }else {
                IModel model = deserialization(sysModel, requestArgs);
                Method method = this.getMethodByName(repository.getClass(), "delete", IModel.class, ITableInfo.class);
                this.execRepository(repository, method, model, sysModel);
                if(model.getObjectId() != null) {
                    MessageSender messageSender = MessageSender.getMessageSender();
                    if(messageSender != null) {
                        DataMessage dataMessage = DataMessage.valueOf(sysModel.getModelCode(), DataMessage.DELETE, model.getObjectId().toString(),
                                null, model, requestArgs.getSysCode(), userCredentials.getName());
                        messageSender.sendMsg(CommandRunTimeArgs.getRunTimeArgs().getDataQueueName(), dataMessage);
                    }
                }
                return "OK";
            }
        } catch (BusinessException businessException) {
            throw businessException;
        } catch (DalFrameException exception) {
            throw new BusinessException(exception.getCode(), exception.getMessage());
        } catch (Exception exception) {
            throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR, exception.getMessage());
        }
    }

    @Override
    public String getBeanName() {
        return "Delete";
    }
}
